_package("alz.core");

_import("alz.core.Request");
_import("alz.core.EventTarget");
_import("alz.core.LocalStorage");
_import("alz.core.DataModel");
_import("alz.core.TagLib");
_import("alz.core.TemplateManager");
_import("alz.core.HistoryManager");

/**
 * 应用基础类，所有的应用都应该是该类的子类
 */
_class("Application", EventTarget, function(){
	var plugins = [  //插件列表
		{"id": "storage" , "clazz": "LocalStorage"   },
		{"id": "model"   , "clazz": "DataModel"      },
		{"id": "taglib"  , "clazz": "TagLib"         },
		{"id": "template", "clazz": "TemplateManager"},
		{"id": "history" , "clazz": "HistoryManager" }
	];
	this.EVENTS = [
		"beforeNetInvoke",  //网络请求参数预处理前，给子类一个在请求发生前修改请求参数的机会
		"beforeCallback"    //网络请求回调被执行前出发，用于处理404,500等错误结果
	];
	/*
	 * 应用配置信息
	 */
	this.__conf = {
		"tags"  : [],  //标签库配置
		"model" : [],  //数据模型配置
		"dialog": {},  //对话框组件配置
		"page"  : []   //伪页面组件配置
	};
	/**
	 * 注册配置数据
	 */
	this.__conf__ = function(data){
		for(var k in data){
			var hash = this.__conf[k];
			/*
			if(!(k in this.__conf)){
				hash = this.__conf[k] = {};
			}else{
				hash = this.__conf[k];
			}
			*/
			for(var i = 0, len = data[k].length; i < len; i++){
				var item = data[k][i];
				if(k == "dialog"){
					if(typeof item.clazz === "string"){
						item.clazz = __context__[item.clazz];
					}
					hash[item.id] = item;  //对话框使用hash存储
				}else{
					hash.push(item);
				}
			}
		}
	};
	this._init = function(){
		_super._init.call(this);
		this._debug = false;    //调试开关
		this._conf = null;      //应用配置信息
		this._params = null;    //应用的参数
		this._contentPane = null;  //{Pane}

		this._plugins = {};     //插件容器
		this._storage = null;   //本地持久存储
		this._model = null;     //数据模型(数据层)
		this._taglib = null;    //标签库
		this._template = null;  //模板引擎
		this._history = null;   //历史记录管理
		this._dialogs = {};     //所有对话框组件

		this._jsonp = false;       //标识是否使用JSONP进行跨域请求
		this._useProxy = false;    //是否使用代理(针对本地开发环境)
		this._useLoading = false;  //是否显示加载中提示
		this._useModel = true;    //加载提示是否模态
		this._customLoading = 0;

		this._lastToastTime = 0;
		this._lastToastInfo = "";
	};
	this.init = function(){
		/*
		for(var i = 0, len = plugins.length; i < len; i++){
			var p = plugins[i];
			var plugin = new p.clazz();
			plugin.create(p.id, this);
			this._plugins[p.id] = plugin;
			//this["_" + p.id] = plugin;
		}
		*/
		if(window.localStorage){
			this._storage = new LocalStorage(window.localStorage);
			this._storage.create("storage", this);
		}
		this._model = new DataModel();
		this._model.create("model", this);
		this._taglib = new TagLib();
		this._taglib.create("taglib", this);
		this._template = new TemplateManager();
		this._template.create("template", this);
		this._history = new HistoryManager();
		this._history.create("history", this);
	};
	this.dispose = function(){
		if(this._contentPane){
			//this._contentPane.dispose();
			this._contentPane = null;
		}
		this._history.dispose();
		this._history = null;
		this._template.dispose();
		this._template = null;
		this._taglib.dispose();
		this._taglib = null;
		this._model.dispose();
		this._model = null;
		if(this._storage){
			this._storage.dispose();
			this._storage = null;
		}
		for(var k in this._plugins){
			this._plugins[k].dispose();
			//this["_" + k] = null;
			delete this._plugins[k];
		}
		_super.dispose.apply(this);
	};
	this.setConf = function(v){
		this._conf = v;
		if(v.conf){
			this._debug = v.conf.debug || this._debug;
		}
	};
	this.setParams = function(v){
		this._params = v;
	};
	this.getContentPane = function(){
		return this._contentPane;
	};
	this.setContentPane = function(v){
		this._contentPane = v;
	};
	/**
	 * 初始化各种配置信息
	 */
	this.initConf = function(tpl){
		//注册数据模型
		this._model.regModels(this.findConf("model"));
		//注册组件的自定义标签
		this._taglib.regTags(this.findConf("tags"));
		//注册模板库
		this._template.reg(runtime.getTplData(tpl));
	};
	this.isFirstRun = function(){
		//this._storage.getItem("citylife_first") != "1"
		return this._model.getConfData("firstrun") == 1/* && this._className == "AppCityLife"*/;
	};
	this.toast = function(str){
		var now = new Date().getTime();
		if(this._lastToastInfo == str && now - this._lastToastTime < 2000){  //忽略小于两秒的重复提示信息
			return;
		}
		this._lastToastTime = now;
		this._lastToastInfo = str;
		CloudAPI.Utility.toast(str);
	};
	this.showNetError = function(){
		//网络超时或出错，请稍后再试！
		//网络连接出错, 请检查您的网络设置!
		//网络不可用，点击确定，检查网络设置
		//window.alert("您的网络未连接或中断");
		this.toast("请求失败，请稍候再试");
		/*
		var params = {
			"title": "系统提示",
			"msg"  : "网络不可用，是否检查网络？"
		};
		this.dlgInvoke("confirm", this, params, this, function(dlg, act){
			if(act == "dlg_ok"){
				runtime._cloudapi.Device.DeviceStateInfo.wirelessSetting();  //启动无线网络设置界面
			}
		});
		*/
	};
	this.showOperationFailed = function(){
		this.toast("操作失败，请重试或刷新");
		/*
		var params = {
			"title": "系统提示",
			"msg"  : "操作失败，请重试或刷新"
		};
		this.dlgInvoke("msgbox", this, params, this, function(dlg, act){
			if(act == "dlg_ok"){
			}
		});
		*/
	};
	this.customLoading = function(agent, func){
		this._customLoading = runtime._task.add(agent, func, null, "event");
	};
	this.abort = function(cbid, hold){
		if(this._useLoading){
			runtime.getWorkspace().hideTip();
		}
		runtime._ajax.abort(cbid, hold);
	};
	this.retry = function(cbid){
		runtime._ajax.retry(cbid);
	};
	/**
	 * 网络请求调用接口
	 * @param {String} method GET|POST 异步请求的方法
	 * @param {String} url 请求地址
	 * @param {String|Object} params 请求参数
	 * @param {String} type text|json|xml 请求数据的格式
	 * @param {Object|Function} agent 代理对象或匿名回调函数
	 * @param {Function|String} func 匿名回调函数或方法名
	 */
	this.netInvoke = function(method, url, params, type, agent, func){
		runtime.log("[Application::netInvoke]" + url);
		if(!this.isFirstRun() && runtime._cloudapi.Device.DeviceStateInfo.isNetworkAvailable() == "false"){
			this.showNetError();
			return 0;
		}else{
			var req = new Request(method, url, params, type, agent, func);  //一个网络请求对象
			/*
			var req = {
				"method": method,
				"url"   : url,
				"params": params,
				"type"  : type,
				"cbid"  : -1,     //回调任务id
				"agent" : agent,
				"func"  : func
			};
			this.fireEvent({"type": "beforeNetInvoke", "req": req});
			*/
			if(this._useLoading){
				if(this._customLoading != 0){
					runtime._task.execute(this._customLoading, ["start"]);
				}else{
					runtime.getWorkspace().showTipMsg("正在请求数据...", this._useModel, true);  //[TODO]模态的加载提示需要考虑超时隐藏问题
				}
			}
			return runtime._ajax.append(this, req);
		}
	};
	this.checkError = function(json){
		//if(!json){
		if(typeof json === "undefined" || json === null){
			runtime.log("[Application::checkError1]showOperationFailed");
			this.showOperationFailed();
			return false;
		}
		if(typeof json == "object" && "code" in json && "msg" in json && "data" in json){  //必须符合约定的格式，才进行下面的检查
			if(json.code >= 0){
				return true;
			}else{
				switch(json.code){
				case -1000:
				case -1001:
				case -1002:
					this.showNetError();
					break;
				default:
					runtime.log("[Application::checkError2]showOperationFailed");
					this.showOperationFailed();
					break;
				}
				return false;
			}
		}else{
			return true;
		}
	};
	/**
	 * @return {Boolean} 结果影响被依赖的任务的执行
	 */
	this.beforeCallback = function(data){
		var ret;
		if(typeof this.onBeforeCallback != "function"){
			ret = this.checkError(data);
		}else{
			ret = this.fireEvent({"type": "beforeCallback", "data": data});
		}
		if(typeof ret !== "boolean"){
			ret = true;
		}
		if(this._useLoading){
			if(this._customLoading != 0){
				runtime._task.execute(this._customLoading, ["stop"]);
				runtime._task.remove(this._customLoading);
				this._customLoading = 0;
			}else{
				runtime.getWorkspace().hideTip();
			}
		}
		return ret;
	};
	this.dataInvoke = function(){
		this._model.dataInvoke.apply(this._model, arguments);
	};
	/**
	 * 调用一个对话框组件（创建，重置）
	 * @param key {String} 要创建的对话框的名字（类名 + "_" + id）
	 * @param app {Application} 对话框所属的应用
	 * @param params {Object} 创建参数
	 * @param agent {Object} 回调代理对象
	 * @param func {String|Function} 回调函数
	 */
	this.dlgInvoke = function(key, app, params, agent, func){
		var id = key.split("_")[0];
		var dlg = this._dialogs[key];
		if(!dlg){
			var conf = this.__conf["dialog"];
			var clazz = conf[id in conf ? id : "dialog"].clazz;
			dlg = new clazz();
			dlg.setApp(app || this);
			dlg.create(this._contentPane, this, params);
			this._dialogs[key] = dlg;
		}
		if(agent){
			dlg.setReq(runtime._task.add(agent, func));
		}
		dlg.show();
		dlg.reset(params);
		return dlg;
	};
	this.getTagClass = function(tag){
		return this._taglib.mapTagClass(tag);
	};
	this.getModel = function(key){
		return this._model.getModel(key);
	};
	this.getTpl = function(name){
		return this._template.getTpl(name);
	};
	/*
	this.findConf = function(type, k){
		var hash = this.__conf[type];
		return hash[k in hash ? k : type];  //默认值和type参数一直
	};
	*/
	this.findConf = function(type){
		return this.__conf[type];
	};
	this.doAction = function(act, sender){
	};
});